import jwt
import base64
import hashlib
import random
from Crypto.Cipher import AES
from datetime import datetime
from processing.Sql_DataFrom import ProJosn

# 生成token
def ProToken(data):
    encoded = jwt.encode(data, "secret", algorithm="HS256")
    return encoded

# 解密token
def DecodeToken(data):
    result = jwt.decode(data, "secret", algorithms=["HS256"])
    return result

# 生成id
def Random_id(randomlength,head,type='str'):
    if type == 'str':
        base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'
    else:
        base_str = '0123456789'
    random_str = ''
    length = len(base_str) - 1
    for i in range(randomlength):
        random_str += base_str[random.randint(0, length)]

    return head+random_str[:-len(head)]


# from Crypto.Cipher import AES
# 加密值
_aes = 'liying'
def addStrToSpecifyLen(s,specifyLen=0):
    """
    s不是specifyLen的倍数那就补足为specifyLen的倍数
    :param s: 需要加密的参数
    :param specifyLen: 指定参数的位数
    :return: 补足位数的参数
    """
    if specifyLen <= 0:
        specifyLen = 1;
    while len(s) % specifyLen != 0:
        s += '\0'
    return s.encode(encoding='utf-8')

class Sercret_all():
    # def __init__(self,s_data):

    # md5加密
    def Md5(self,s_data):
        try:
            # 加密类型必须是字符

            m_data = str(s_data)
            md5 = hashlib.md5()
            md5.update(m_data.encode('utf-8'))
            data = md5.hexdigest()

            return data
        except:
            return '加密失败!'

    # aes加密  # 非对称加密
    def encrypt_aes(self,s_data):
        """
        aes的ecb模式加密
        :param data: 加密数据
        :param aes_key: 加密的秘钥
        :return: 加密之后的密文
        """
        # 初始化加密器
        aes = AES.new(addStrToSpecifyLen(_aes, 16), AES.MODE_ECB)  # 密钥
        # 先进行aes加密
        encrypt = aes.encrypt(addStrToSpecifyLen(s_data, 16)) # 数据
        # 用base64转成字符串形式
        encrypted_text = str(base64.encodebytes(encrypt), encoding='utf-8')  # 执行加密并转码返回bytes
        return encrypted_text

    # aes解密
    def decrypt_aes(self,data):
        """
        aes的ecb模式解密
        :param data: 待解密数据
        :param aes_key: 加密的秘钥(加密之前的数据)
        :return: 解密之后的数据
        """
        # 初始化加密器
        aes = AES.new(addStrToSpecifyLen(_aes, 16), AES.MODE_ECB)
        # 优先逆向解密base64成bytes
        base64_decrypted = base64.decodebytes(addStrToSpecifyLen(data, 16))
        # 执行解密密并转码返回str
        decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '')

        return decrypted_text



def Serialization(data,db):

    for i in data:

        i['register_date'] = datetime.strftime(i['register_date'],"%Y-%m-%d %H:%M:%S")
        # 查询单独角色菜单

        role_sql = " select title,menu_list from authority_roles where status='normal' "
        r_num = 0
        for r in i['role_id'].split(','):
            if r_num == 0:
                role_sql += " and id={} ".format(r)
            else:
                role_sql+= " or id={} ".format(r)
            r_num += 1
        roles = []
        menus = []


        for rl in db.find_all(role_sql):

            if rl[1]:
                roles.append(rl[0])
                ausers_roles_sql = f" select menu_list from ausers_roles where user_id=%s "
                clone_menu = db.find_all(ausers_roles_sql, (i['user_id']))[0][0]
                if clone_menu:
                    menus.append(rl[1] +','+clone_menu)
                else:
                    menus.append(rl[1])
        i['roles'] = roles or ['admin']

        menu_str = ''
        # 把角色权限和菜单权限结合去重
        if len(menus):
            for ii in menus:
                if not menu_str:
                    menu_str += ii
                else:
                    menu_str+= ',' + ii
        # i['role_menu'] = menu_str

        menu_list = []
        #   合并去重
        if menu_str:
            sa = ',' + menu_str
        else:
            sa =''

        if not i['menu_list']:
            i['menu_list'] = ''
            if menu_str:
                sa = menu_str


        [menu_list.append(int(i)) for i in (i['menu_list'] + sa).split(',') if i not in menu_list]

        i['menu_id'] =  (menu_list)

        i['role_id'] = int(i['role_id'])
        #     请求菜单权限
        menu_sql = """ select id,title,name,icon,path,redirect,uid,showLink,menuRank,showParent,fixedTag,hiddenTag,
                            keepAlive,frameLoading,frameSrc,auths,activePath,leaveTransition,enterTransition,extraIcon from authority_menus where status='normal' """
        num = 0
        for jj in menu_list:
            if num == 0:

                menu_sql += f" and id={jj} "
            menu_sql += f" or id={jj} "
            num += 1
        list1 = []

        menuList_data = ProJosn(db.find_all(menu_sql), ['id','title','name','icon','path','redirect','uid','showLink','menuRank','showParent','fixedTag','hiddenTag',
                                                        'keepAlive','frameLoading','frameSrc','auths','activePath','leaveTransition','enterTransition','extraIcon',
            ],'list').to_dict(orient='records')

        for jj in menuList_data:
            if jj['uid'] == 0:
                jj['children'] = []

                jj['meta'] = {
                    'icon':jj['icon'],
                    'title':jj['title'],
                    'rank':jj['menuRank'],
                    'showLink':jj['showLink'],
                    'showParent':jj['showParent'],
                    'fixedTag':jj['fixedTag'],
                    'hiddenTag':jj['hiddenTag'],
                    'keepAlive':jj['keepAlive'],
                    'frameLoading':jj['frameLoading'],
                    'frameSrc':jj['frameSrc'],
                    'auths':jj['auths'],
                    'activePath':jj['activePath'],
                    'leaveTransition':jj['leaveTransition'],
                    'enterTransition':jj['enterTransition'],
                    'extraIcon':jj['extraIcon'],

                }
                list1.append(jj)
                if jj['redirect']:
                    continue
                else:
                    del jj['redirect']

                del jj['icon']
                del jj['name']
        i['menus'] = list1
        try:
            for kk in i['menus']:
                for i in menuList_data:

                    if kk['id'] == i['uid']:

                        i['meta'] = {
                            'icon': i['icon'],
                            'title': i['title'],
                            # 'rank':  i['menuRank'],
                            'showLink': i['showLink'],
                            # 'showParent': i['showParent'],
                            'fixedTag': i['fixedTag'],
                            'hiddenTag': i['hiddenTag'],
                            'keepAlive': i['keepAlive'],
                            'frameLoading': i['frameLoading'],
                            'frameSrc': i['frameSrc'],
                            'auths': i['auths'],
                            'activePath': i['activePath'],
                            'leaveTransition': i['leaveTransition'],
                            'enterTransition': i['enterTransition'],
                            'extraIcon': i['extraIcon'],
                        }
                        if i['redirect']:
                            continue
                        else:
                            del i['redirect']
                        del i['icon']
                        # del i['name']
                        # del i['uid']
                        # del i['id']
                        del i['title']

                        kk['children'].append(i)
                    else:
                        continue
                # 菜单排序
                kk['children'] = sorted(kk['children'], key=lambda x: x['menuRank'])
        except Exception as error:
            print(error)
    return data

def date_format(data,type='float'):
    x = [1,2,3,4,5,6,7,8,9,10,11,12]
    y = [0,0,0,0,0,0,0,0,0,0,0,0]

    for j in [1,2,3,4,5,6,7,8,9,10,11,12]:
        for i in data:
            if j == i[0]:
                if type == 'float':
                    y[j-1] = round(i[1],2)
                else:
                    y[j - 1] = int(i[1])
    return x,y



